//
// Created on 2025/11/20.
// Author 秦光磊.
#include "drawbase/draw_base.h"
#include "constant/constant.h"
#include "gencoordinate/gen_coordinate.h"
#include "render/egl_core.h"
#include <hilog/log.h>
#include <algorithm>
/**
 * 给定起始坐标，画一条线段，可以是实线，也可以是虚线
 * @param eglCore egl核心绘制功能
 * @param fromVertices 线段的起始位置
 * @param fromSize 起始位置坐标数字个数，一般是3
 * @param toVertices 线段的结束位置
 * @param toSize 结束位置坐标数字个数，一般是3
 * @param drawColor 绘制颜色
 * @param colorSize 颜色数字，一般是4
 * @param geometryAttribute
 * 几何参数用到geometryAttribute[0]:geometryAttribute[0]为1表示虚线，为3表示实线
 * 几何参数用到geometryAttribute[1]:geometryAttribute[1]为1表示画小图，为2表示画大图
 * 几何参数其它值随意
 * @param attrSize 至少为2
 * @return true绘制完成， false绘制失败
 */
bool DrawBase::DrawLineSegment(EGLCore *eglCore, std::vector<GLfloat> &fromVertices, int fromSize,
                               std::vector<GLfloat> &toVertices, int toSize, GLfloat drawColor[4], int colorSize,
                               int *geometryAttribute, int attrSize) {
    if ((fromSize < 3) || (toSize < 3) || (colorSize < 4) || (attrSize < 2)) {
        OH_LOG_Print(
            LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase",
            "%{public}s param size error.fromSize:%{public}d,toSize%{public}d,colorSize%{public}d,attrSize%{public}d.",
            __func__, fromSize, toSize, colorSize, attrSize);
        return false;
    }
    if (fromVertices.size() < fromSize) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase",
                     "%{public}s fromVertices大小不对。fromVertices.size():%zu.", __func__, fromVertices.size());
        return false;
    }
    if (toVertices.size() < toSize) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase",
                     "%{public}s toVertices大小不对。toVertices.size():%zu.", __func__, toVertices.size());
        return false;
    }
    if (eglCore == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase", "%{public}s eglCore为nullptr.", __func__);
        return false;
    }
    if (geometryAttribute == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase", "%{public}s geometryAttribute为nullptr.",
                     __func__);
        return false;
    }
    if (geometryAttribute[0] == 1) {
        // 画一条虚线段
        DrawLineSegmentDotted(eglCore, fromVertices, fromSize, toVertices, toSize, drawColor, colorSize,
                              geometryAttribute, attrSize);
    } else if (geometryAttribute[0] == 3) {
        //
        DrawLineSegmentSolid(eglCore, fromVertices, fromSize, toVertices, toSize, drawColor, colorSize,
                             geometryAttribute, attrSize);
    } else {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase",
                     "%{public}s 几何参数既不是画实线也不是画虚线.geometryAttribute[0]:%{public}d.", __func__,
                     geometryAttribute[0]);
        return false;
    }
    return true;
}

/**
 * 给定起始坐标，画一条实线段，业务上，使用DrawLineSegment调用，不要直接使用。
 * @param eglCore egl核心绘制功能
 * @param fromVertices 线段的起始位置
 * @param fromSize 起始位置坐标数字个数，一般是3
 * @param toVertices 线段的结束位置
 * @param toSize 结束位置坐标数字个数，一般是3
 * @param drawColor 绘制颜色
 * @param colorSize 颜色数字，一般是4
 * @param geometryAttribute 几何规格内容。geometryAttribute[0]为3表示画实线
 * 几何参数用到geometryAttribute[0]:需要为3表示实线
 * 几何参数用到geometryAttribute[1]:geometryAttribute[1]为1表示画小图，为2表示画大图
 * @param attrSize 由于用到geometryAttribute[1]，所以大小至少为2
 * @return true绘制完成， false绘制失败
 */
bool DrawBase::DrawLineSegmentSolid(EGLCore *eglCore, std::vector<GLfloat> &fromVertices, int fromSize,
                                    std::vector<GLfloat> &toVertices, int toSize, GLfloat drawColor[4], int colorSize,
                                    int *geometryAttribute, int attrSize) {
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "DrawBase", "%{public}s start.", __func__);
    if ((fromSize < 3) || (toSize < 3) || (colorSize < 4) || (attrSize < 2)) {
        OH_LOG_Print(
            LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase",
            "%{public}s param size error.fromSize:%{public}d,toSize%{public}d,colorSize%{public}d,attrSize%{public}d.",
            __func__, fromSize, toSize, colorSize, attrSize);
        return false;
    }
    if (geometryAttribute[0] != 3) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase",
                     "%{public}s 绘制实线段的几何参数不对，geometryAttribute[0]：%{public}d.", __func__,
                     geometryAttribute[0]);
        return false;
    }
    if (fromVertices.size() < fromSize) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase",
                     "%{public}s fromVertices大小不对。fromVertices.size():%zu.", __func__, fromVertices.size());
        return false;
    }
    if (toVertices.size() < toSize) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase",
                     "%{public}s toVertices大小不对。toVertices.size():%zu.", __func__, toVertices.size());
        return false;
    }
    if (eglCore == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase", "%{public}s eglCore为nullptr.", __func__);
        return false;
    }
    if (geometryAttribute == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase", "%{public}s geometryAttribute为nullptr.",
                     __func__);
        return false;
    }
    // 直线就两个点相连,一共6个数字
    std::vector<GLfloat> shapeVertices;
    shapeVertices.push_back(fromVertices[0]);
    shapeVertices.push_back(fromVertices[1]);
    shapeVertices.push_back(fromVertices[2]);
    shapeVertices.push_back(toVertices[0]);
    shapeVertices.push_back(toVertices[1]);
    shapeVertices.push_back(toVertices[2]);
    // 绘制
    bool drawObj = eglCore->DrawAnyObject(shapeVertices, shapeVertices.size(), drawColor, colorSize, geometryAttribute, attrSize);
    if (!drawObj) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase",
                     "%{public}s,DrawAnyObject fail,详见DrawAnyObject里日志。", __func__);
        return false;
    }
    return true;
}
/**
 * 给定起始坐标，画一条虚线段，业务上，使用DrawLineSegment调用，不要直接使用。
 * @param eglCore egl核心绘制功能
 * @param fromVertices 线段的起始位置
 * @param fromSize 起始位置坐标数字个数，一般是3
 * @param toVertices 线段的结束位置
 * @param toSize 结束位置坐标数字个数，一般是3
 * @param drawColor 绘制颜色
 * @param colorSize 颜色数字，一般是4
 * @param geometryAttribute 几何规格内容。geometryAttribute[0]为1表示画虚线
 * 几何参数用到geometryAttribute[0]:geometryAttribute[0]为1表示虚线，为3表示实线
 * 几何参数用到geometryAttribute[1]:geometryAttribute[1]为1表示画小图，为2表示画大图
 * 几何参数其它值随意
 * @param attrSize 用到geometryAttribute[0]与[1]，至少为2
 * @return true绘制完成， false绘制失败
 */
bool DrawBase::DrawLineSegmentDotted(EGLCore *eglCore, std::vector<GLfloat> &fromVertices, int fromSize,
                                     std::vector<GLfloat> &toVertices, int toSize, GLfloat drawColor[4], int colorSize,
                                     int *geometryAttribute, int attrSize) {
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "DrawBase", "%{public}s start.", __func__);
    if ((fromSize < 3) || (toSize < 3) || (colorSize < 4) || (attrSize < 2)) {
        OH_LOG_Print(
            LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase",
            "%{public}s param size error.fromSize:%{public}d,toSize%{public}d,colorSize%{public}d,attrSize%{public}d.",
            __func__, fromSize, toSize, colorSize, attrSize);
        return false;
    }
    if (geometryAttribute[0] != 1) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase",
                     "%{public}s 绘制虚线段的几何参数不对，geometryAttribute[0]：%{public}d.", __func__,
                     geometryAttribute[0]);
        return false;
    }
    if (fromVertices.size() < fromSize) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase",
                     "%{public}s fromVertices大小不对。fromVertices.size():%zu.", __func__, fromVertices.size());
        return false;
    }
    if (toVertices.size() < toSize) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase",
                     "%{public}s toVertices大小不对。toVertices.size():%zu.", __func__, toVertices.size());
        return false;
    }
    if (eglCore == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase", "%{public}s eglCore为nullptr.", __func__);
        return false;
    }
    if (geometryAttribute == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase", "%{public}s geometryAttribute为nullptr.",
                     __func__);
        return false;
    }
    // 获取两点之间的坐标
    std::vector<GLfloat> dottedCoordinates = GenCoordinate::GenDottedStraightLineCoordinate(
        fromVertices, fromSize, toVertices, toSize, geometryAttribute, attrSize);
    // 开始绘制
    bool drawObj = eglCore->DrawAnyObject(dottedCoordinates, dottedCoordinates.size(), drawColor, colorSize,
                                          geometryAttribute, attrSize);
    if (!drawObj) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase",
                     "%{public}s,DrawAnyObject fail,详见DrawAnyObject里日志。", __func__);
        return false;
    }
    return true;
}
/**
 * 在XOY平面上画椭圆上一段,从Y轴正方向往X轴正方向的角度为startAngle，arcAngle为增量角度就是弧度
 * @param eglCore 帧绘制核心操作
 * @param a 椭圆的半轴长a
 * @param b 椭圆的半轴长b
 * @param centerVertices 椭圆中心坐标
 * @param centerSize 中心坐标数字个数，一般为3
 * @param drawColor 绘制颜色
 * @param colorSize 颜色数字个数，一般为4
 * @param startAngle 初始角度：以Y轴正方向为基准，顺时针的角度
 * @param arcAngle 增量角度
 * @param geometryAttribute 几何参数
 * 几何参数用到geometryAttribute[0]:geometryAttribute[0]为1表示虚线，为3表示实线
 * 几何参数用到geometryAttribute[1]:geometryAttribute[1]为1表示画小图，为2表示画大图
 * 几何参数其它值随意
 * @param attrSize 由于用到geometryAttribute[0]与geometryAttribute[1]，所以大小至少是2个
 * @return
 */
bool DrawBase::DrawOneEllipseArc(EGLCore *eglCore, float a, float b, std::vector<GLfloat> &centerVertices,
                                 int centerSize, GLfloat drawColor[4], int colorSize, float startAngle, float arcAngle,
                                 int *geometryAttribute, int attrSize) {
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "DrawBase", "%{public}s start.", __func__);
    if ((centerSize < 3) || (colorSize < 4) || (attrSize < 2)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase",
                     "%{public}s param size error.centerSize:%{public}d,colorSize%{public}d,attrSize%{public}d.",
                     __func__, centerSize, colorSize, attrSize);
        return false;
    }
    if (centerVertices.size() < centerSize) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase",
                     "%{public}s startVector大小不对。centerVertices.size():%zu.", __func__, centerVertices.size());
        return false;
    }
    if (eglCore == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase", "%{public}s eglCore为nullptr.", __func__);
        return false;
    }
    if (geometryAttribute == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase", "%{public}s geometryAttribute为nullptr.",
                     __func__);
        return false;
    }
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "DrawBase", "%{public}s 参数值a：%{public}f,b:%{public}f.",
                 __func__, a, b);
    if ((a <= 0) || (b <= 0)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase", "%{public}s a与b不能为0.", __func__);
        return false;
    }
    // 用来存储椭圆坐标
    std::vector<GLfloat> ellipseCoordinates = GenCoordinate::GenOneEllipseArcCoordinates(
        a, b, centerVertices, centerSize, startAngle, arcAngle, geometryAttribute, attrSize);
    // 坐标类型转换
    int vertSize = ellipseCoordinates.size();
    OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "DrawBase", "%{public}s 数字数量%{public}d.", __func__,
                 vertSize);
    int i = 0;
    for (GLfloat item : ellipseCoordinates) {
        OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_PRINT_DOMAIN, "DrawBase", "%{public}s 第%{public}d个元素的值为%{public}f.",
                     __func__, i, item);
        i++;
    }
    // 开始绘制
    bool drawObj =
        eglCore->DrawAnyObject(ellipseCoordinates, vertSize, drawColor, colorSize, geometryAttribute, attrSize);
    if (!drawObj) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "DrawBase",
                     "%{public}s,DrawAnyObject fail,详见DrawAnyObject里日志。", __func__);
        return false;
    }
    return true;
}
